﻿#region LicenseHeader

// Copyright 2012 The Trustees of Indiana University.  All rights reserved.
// 
// The Indiana University licenses this file to you under the Apache License, 
// Version 2.0 (the "License"); you may not use this file except in compliance 
// with the License.  You may obtain a copy of the License at 
// 
// http://www.apache.org/licenses/LICENSE-2.0
// 
// Unless required by applicable law or agreed to in writing, software 
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
//  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  
// See the License for the specific language governing permissions and 
// limitations under the License.
// 
// @author Thilina Gunarathne (tgunarat@indiana.edu)

#endregion

using System;
using System.Collections.Generic;
using System.Diagnostics;
using AzureMRCore.Client;
using Credentials;
using Microsoft.WindowsAzure;

namespace SWGClient
{
    internal class SWGClient
    {
        private static void Main(string[] args)
        {
            /*if (args.Length < 3)
            {
                Console.Out.WriteLine("Usage: SWGClient.exe <jobID> <numSequences> <blockSize>");
                return;
            }*/

            CloudStorageAccount storageAccount = ClientCredentials.GetClientStorageAccount();

            double blockSize = 20; // Convert.ToDouble(args[2]);
            double numSequences = 100; // Convert.ToDouble(args[1]);
            string jobID = "00swgt5"; //args[0];

            //Convert.ToInt32(args[2]));
            // ServicePointManager.UseNagleAlgorithm = false;
            // ServicePointManager.Expect100Continue = false;
            //ServicePointManager.CheckCertificateRevocationList = false;
            // ServicePointManager.DefaultConnectionLimit = 50;

            int numReduceTasks = (int) Math.Ceiling(numSequences/blockSize);
            List<string> mapTasks = GetMapTasks("lib\\haixu_group_10.fasta", (int) blockSize, (int) numSequences, 3240);

            Stopwatch timer = Stopwatch.StartNew();
            TwisterAzureClient azureClient = new TwisterAzureClient(storageAccount, jobID, "mapswgt1", "redswgt1");
            azureClient.ProcessMapRed("SWGMBFMR", mapTasks, 0, "", numReduceTasks, "j" + jobID + "out");

            azureClient.WaitForCompletion(500);
            Console.Out.WriteLine("Job Complete. Elapsed Time (ms) :" + timer.ElapsedMilliseconds);
            // TwisterAzureClient.Cleanup(jobID, ("j" + jobID + "out").ToLower(), storageAccount);
            Console.In.ReadLine();
        }

        private static List<string> GetMapTasks(string filename, int blockSize, int noOfSequences, int blocks)
        {
            string BREAK = "$";
            List<string> mapTasks = new List<string>();
            int noOfDivisions = (int) Math.Ceiling(noOfSequences/(double) blockSize);
            int totalBlocks = (noOfDivisions*(noOfDivisions + 1))/2;
            Console.Out.WriteLine("No of divisions :" + noOfDivisions
                                  + "\nNo of blocks :" + totalBlocks + "\nBlock size :" + blockSize);

            //to get the last sequence number
            noOfSequences = noOfSequences - 1;

            int count = 0;
            for (int row = 0; row < noOfDivisions; row++)
            {
                for (int column = 0; column < noOfDivisions; column++)
                {
                    // using the load balancing algorithm to select the blocks
                    // include the diagonal blocks as they are blocks, not
                    // individual pairs
                    if (((row >= column) & ((row + column)%2 == 0))
                        | ((row <= column) & ((row + column)%2 == 1)))
                    {
                        if (count < blocks)
                        {
                            int xStart = row*blockSize;
                            int xBlockEnd = xStart + blockSize - 1;
                            int xEnd = (xBlockEnd <= noOfSequences) ? xBlockEnd : noOfSequences;
                            int yStart = column*blockSize;
                            int yBlockEnd = yStart + blockSize - 1;
                            int yEnd = (yBlockEnd <= noOfSequences) ? yBlockEnd : noOfSequences;
                            //"0_9_0_9_1"
                            String value = xStart + BREAK + xEnd + BREAK + yStart + BREAK + yEnd + BREAK + filename +
                                           BREAK + blockSize + BREAK;
                            // Console.Out.WriteLine(value);
                            mapTasks.Add(value);
                            count++;
                        }
                    }
                }
            }
            return mapTasks;
        }
    }
}